﻿using System;
using System.Threading.Tasks;
using Pay.Core;

namespace Pay.DTO {
	/// <summary>
	/// 返回响应消息： result_code是错误代码，默认1000成功，其它失败；result_msg是返回响应消息 data是业绩结果：可能无；
	/// </summary>
	[Serializable]
	public class ApiResultMessage {
		/// <summary>
		/// 平台统一私钥，要反共钥给O商
		/// </summary>
		private const string _private_key = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMIdAFP+N2ba7UUYe6KQfl25ZN+DADP7sMGqWHuphdJ6Zt0BFeTjYZpfFT6exepW24QM/OEmDPf2cWJluK7K+RkDzt8G1YXZY1eL0u8F0+0dFZsFnI6+7hZ3WSbMH4V3KY8Aj2KdvgQFK/g8Plp+XFOEEoA4HvTWGIx60SrT70AxAgMBAAECgYBLP+7moMBdcTVV+d3D8XvrXXmLZD9p54JoMV9H4TntlGHX/xm7t6IYtA+KTQawh6dlk5tctOGGJtVhrclgiXLy4L3qJvjOPS7+MF9gzCAT8OQ6gN33HCo8oYFadpE6YgcbjwaLORm0+ir5CNFNrOeaE+5gQSYsFxZe+wrGDFFXIQJBAN1TZ4WYnLfbHSvMd1z+SyzK/lrPpAhSnRhcGCZYrz7DsrqTMlRUiudJEoDyN+jTxobnw/GzyFuhJoS2yldTt80CQQDghjL/Lsqj2O0D5DItjS7RCGqYx3nRA5M1nXkipWTUFTF6TPAk7RwiI5h9Bafz5U3GSVh2o8pXk9Ack7nAlr31AkAI+62j+oHB5J7WfEIMADZE5yhTv0HFJLVDm9lPFSJnxcGnWPod+iB5KroZibtDM/VG3HlTghyLu4q4sEKeMMOxAkEAlFsYR1V7wFgOBIw8O60WSjjtdpYX/+wE0WCEMkhnH1wBnXZJF501AbnTgIjEOXxCr8q3EW2YvdWFpdxW2NLCIQJBAL4+QjSyzrbTrfvDLw2wbuKgduKeRvefkeMu3VvRMiVZz0GMoPV8PWXhOeOmIyivpL9HYJgBGRJvK/2RaNGc5wM=";
		/// <summary>
		/// 共钥给O商
		/// </summary>
		//private const string _public_key = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCHQBT/jdm2u1FGHuikH5duWTfgwAz+7DBqlh7qYXSembdARXk42GaXxU+nsXqVtuEDPzhJgz39nFiZbiuyvkZA87fBtWF2WNXi9LvBdPtHRWbBZyOvu4Wd1kmzB+FdymPAI9inb4EBSv4PD5aflxThBKAOB701hiMetEq0+9AMQIDAQAB";
		private int _result_code = 1000;
		/// <summary>
		/// 默认1000表示成功，其它失败
		/// </summary>
		public int result_code {
			get { return _result_code; }
			set { _result_code = value; }
		}
		/// <summary>
		/// 返回执行结果消息
		/// </summary>
		public string result_msg { get; set; }
		/// <summary>
		/// 除sign自身值外，所以字段以key=value&key2=value2，按key字母顺序排序
		/// </summary>
		public string sign { get; set; }
		/// <summary>
		/// 返回响应消息： result_code是错误代码，默认1000成功，其它失败；result_msg是返回响应消息 data是业绩结果：可能无；
		/// </summary>
		public ApiResultMessage() { }
		public ApiResultMessage(string msg) {
			result_msg = msg;
		}
		public ApiResultMessage(int code, string msg) {
			result_code = code;
			result_msg = msg;
		}

		public void SetSign() {
			var app_sortJson = SecuritySignHelper.JsonToKeyQuery2(this.ToJson());
			var app_sign = RSAFromPkcs.sign(app_sortJson, _private_key, "utf-8");
			this.sign = app_sign;
		}
	}
	/// <summary>
	/// 返回带有LIST集合的响应消息： result_code是错误代码，默认1000成功，其它失败；result_msg是返回响应消息 data是业绩结果：可能无；
	/// </summary>
	[Serializable]
	public class ApiDataResultMessage<T> : ApiResultMessage {
		/// <summary>
		/// data是业绩结果：可能无
		/// </summary>
		public T data { get; set; }

		public ApiDataResultMessage(T result) {
			data = result;
		}
	}

	/// <summary>
	/// 响应消息处理类
	/// </summary>
	public class ApiResultToJson {
		/// <summary>
		/// 成功返回
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="result"></param>
		/// <returns></returns>
		public static ApiResultMessage JsonData<T>(T result) {
			var apiList = new ApiDataResultMessage<T>(result);
			apiList.SetSign();
			return apiList;
		}
		/// <summary>
		/// 成功返回
		/// </summary>
		/// <param name="result_msg"></param>
		/// <returns></returns>
		public static ApiResultMessage Success(string result_msg) {
			var result = new ApiResultMessage(result_msg);
			result.SetSign();
			return result;
		}
		/// <summary>
		/// 失败返回
		/// </summary>
		/// <param name="result_msg"></param>
		/// <returns></returns>
		public static ApiResultMessage Fail(string result_msg) {
			var result = new ApiResultMessage(0, result_msg);
			result.SetSign();
			return result;
		}
		/// <summary>
		/// 成功返回
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="result"></param>
		/// <returns></returns>
		public static T Json<T>(T result) where T : ApiResultMessage, new() {
			result.SetSign();
			return result;
		}
		/// <summary>
		/// 成功返回
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="msg"></param>
		/// <param name="result"></param>
		/// <returns></returns>
		public static T Json<T>(string msg, T result) where T : ApiResultMessage, new() {
			result.result_msg = msg;
			result.SetSign();
			return result;
		}
		/// <summary>
		/// 成功返回
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="msg"></param>
		/// <param name="result"></param>
		/// <returns></returns>
		public static async Task<T> JsonAsync<T>(string msg, T result) where T : ApiResultMessage, new() {
			Task<T> t1 = Task.Factory.StartNew(() => {
				result.result_msg = msg;
				result.SetSign();
				return result;
			});
			return await t1;
		}
		/// <summary>
		/// 失败返回
		/// </summary>
		/// <param name="msg"></param>
		/// <returns></returns>
		public static T Json<T>(string msg) where T : ApiResultMessage, new() {
			var result = new T {
				result_msg = msg,
				result_code = 0
			};
			result.SetSign();
			return result;
		}
		/// <summary>
		/// 失败返回
		/// </summary>
		/// <param name="msg"></param>
		/// <returns></returns>
		public static T Json<T>(string msg, int result_code) where T : ApiResultMessage, new() {
			var result = new T {
				result_msg = msg,
				result_code = result_code
			};
			result.SetSign();
			return result;
		}
		/// <summary>
		/// 失败返回
		/// </summary>
		/// <param name="msg"></param>
		/// <returns></returns>
		public static async Task<T> JsonAsync<T>(string msg) where T : ApiResultMessage, new() {
			Task<T> t1 = Task.Factory.StartNew(() => {
				var result = new T {
					result_msg = msg,
					result_code = 0
				};
				result.SetSign();
				return result;
			});
			return await t1;
        }
        /// <summary>
        /// 失败返回
        /// </summary>
        /// <param name="msg"></param>
        /// <returns></returns>
        public static async Task<T> JsonAsync<T>(string msg, int result_code) where T : ApiResultMessage, new() {
            Task<T> t1 = Task.Factory.StartNew(() => {
                var result = new T {
                    result_msg = msg,
                    result_code = result_code
                };
                result.SetSign();
                return result;
            });
            return await t1;
        }
    }
}
